package com.bjgraphite.report.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bjgraphite.report.domain.request.WorkHourReportRequest;
import com.bjgraphite.report.domain.dto.WorkHourReportDTO;
import com.bjgraphite.report.domain.entity.WorkHourReportDO;
import com.bjgraphite.report.domain.entity.WorkHourReportReptDO;
import com.bjgraphite.report.enums.BizErrorCode;
import com.bjgraphite.report.exception.ReportExcepiton;
import com.bjgraphite.report.response.CommonResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import com.kingdee.bos.webapi.sdk.K3CloudApi;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/report")
public class ReportController {

    private final static Logger LOGGER = LoggerFactory.getLogger(ReportController.class);


    @GetMapping("/workHourReport")
    public CommonResponse<List<WorkHourReportDTO>> workHourReport(WorkHourReportRequest workHourReportRequest) {
        LOGGER.info("执行：workHourReport");
        return CommonResponse.result(listWorkHour(workHourReportRequest));
    }

    private List<WorkHourReportDTO> listWorkHour(WorkHourReportRequest workHourReportRequest) {
        try {
            List<WorkHourReportDO> allList = new ArrayList<>();
            List<WorkHourReportDO> list = null;
            for (int i = 0; i < 10000; i++) {
//            list = getSFCOperationReport(i * 100, i * 100 + 100);
//            list = getSFCOperationReport(0, 10000,workHourReportRequest.getStartDate(),workHourReportRequest.getEndDate(),workHourReportRequest.getWorkShopIds());
                list = getSFCOperationReport(i * 200, i * 200 + 200, workHourReportRequest.getStartDate(), workHourReportRequest.getEndDate(), workHourReportRequest.getWorkShopIds());
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                allList.addAll(list);
            }

            LOGGER.info("allList1.size()=" + allList.size());

            for (int i = 0; i < 10000; i++) {
                list = getSFCUnproductiveTime(i * 200, i * 200 + 200, workHourReportRequest.getStartDate(), workHourReportRequest.getEndDate());
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                allList.addAll(list);
            }
            LOGGER.info("allList2.size()=" + allList.size());

            List<WorkHourReportDO> hlist = allList.stream().filter(entity -> {
                return entity.getEmployeeName().equals("胡海荣");
            }).collect(Collectors.toList());

            System.out.println(hlist);


            if (CollectionUtils.isEmpty(allList)) {
                return null;
            }

            String timeUnit = workHourReportRequest.getTimeUnit();
            Map<String, BigDecimal> stringBigDecimalMap = sumAmount(allList, entity -> entity.getEmployeeName(), entity -> entity.getCountWorkTime());

            List<WorkHourReportDTO> resultList = new ArrayList<>();
            WorkHourReportDTO workHourReportDTO = null;
            for (Map.Entry<String, BigDecimal> entry : stringBigDecimalMap.entrySet()) {
                workHourReportDTO = new WorkHourReportDTO();
                workHourReportDTO.setCountWorkTime(entry.getValue());
                if ("hour".equals(timeUnit)) {
                    workHourReportDTO.setCountWorkTime(entry.getValue().divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
                }
                workHourReportDTO.setEmployeeName(entry.getKey());
                resultList.add(workHourReportDTO);
            }
            return resultList;
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        }
        return null;
    }


    private <T extends WorkHourReportDO, M extends Serializable> Map<M, BigDecimal> sumAmount(List<T> list, Function<T, M> groupField, Function<T, BigDecimal> amountField) {

        Map<M, BigDecimal> amountReduceMap = list.parallelStream().collect(Collectors.groupingBy(groupField, Collectors.collectingAndThen(Collectors.toList(), m -> {
            BigDecimal amount = m.parallelStream().map(info -> amountField.apply(info)).reduce(BigDecimal.ZERO, BigDecimal::add);
            return amount;
        })));

        return amountReduceMap;
    }


    // 获取工序汇报列表
    private List<WorkHourReportDO> getSFCOperationReport(Integer startRow, Integer topRowCount, String startDate, String endDate, String workShopIds) {
        try {

            List<WorkHourReportDO> allList = new ArrayList<>();

            String json = "{\"FormId\":\"SFC_OperationReport\",\"FieldKeys\":\"FDATE,FEMPINFOID,FEMPNAME,FMOPRDDEPT,FWORKSHOPID,FMaterialName,FSpecification,F_HD2JBQty,FFinishQty,FACTIVITY3QTY\",\"FilterString\":[{\"Left\":\"(\",\"FieldName\":\"FDATE\",\"Compare\":\">=\",\"Value\":\"" + startDate + "\",\"Right\":\")\",\"Logic\":\"0\"},{\"Left\":\"(\",\"FieldName\":\"FDATE\",\"Compare\":\"<\",\"Value\":\"" + endDate + "\",\"Right\":\")\",\"Logic\":\"0\"},{\"Left\":\"(\",\"FieldName\":\"FWORKSHOPID\",\"Compare\":\"IN\",\"Value\":\"" + workShopIds + "\",\"Right\":\")\",\"Logic\":\"0\"}],\"OrderString\":\"\",\"TopRowCount\":" + topRowCount + ",\"StartRow\":" + startRow + ",\"Limit\":10000,\"SubSystemId\":\"\"}";

            K3CloudApi api = new K3CloudApi();
            String apiResult = api.billQuery(json);

            if (StringUtils.isBlank(apiResult)) {
                return null;
            }

            // System.out.println("apiResult=" + apiResult);

            if (StringUtils.contains(apiResult, "ResponseStatus")) {
                LOGGER.error(apiResult.toString());
                throw new ReportExcepiton(BizErrorCode.SYSTEM_BUSY_ERROR);
            }


            JSONArray jsonArray = JSONArray.parse(apiResult);


            // LOGGER.info("jsonArray.size()=" + jsonArray.size());

            if (jsonArray.size() == 0) {
                return null;
            }

            JSONObject jsonObject = null;
            String employeeName = null;
            BigDecimal planTime = BigDecimal.ZERO;
            BigDecimal finishCount = BigDecimal.ZERO;
            BigDecimal planTimeThree = BigDecimal.ZERO;

            String planTimeStr;
            String finishCountStr;
            String planTimeThreeStr;

            // F_HD2JBQty 计划工时（基本量二）
            // FFinishQty 完工数量
            // F_PPIV_Qty_re5 活动三基本量
            // FACTIVITY3QTY 准备工时（基本量三）

            for (Object object : jsonArray) {
                jsonObject = JSONObject.parseObject(object.toString());

                employeeName = jsonObject.getString("FEMPNAME");



                if (StringUtils.isBlank(employeeName)) {
                    continue;
                }

                WorkHourReportDO workHourReportDO = new WorkHourReportDO();
                workHourReportDO.setDate(jsonObject.getString("FDATE"));
                workHourReportDO.setEmployeeId(jsonObject.getString("FEMPINFOID"));
                workHourReportDO.setEmployeeName(employeeName);
                workHourReportDO.setMoprddept(jsonObject.getString("FMOPRDDEPT"));
                workHourReportDO.setWorkShopId(jsonObject.getString("FWORKSHOPID"));
                workHourReportDO.setMaterialName(jsonObject.getString("FMaterialName"));
                workHourReportDO.setSpecification(jsonObject.getString("FSpecification"));
                planTimeStr = jsonObject.getString("F.HD2JBQty");
                finishCountStr = jsonObject.getString("FFinishQty");
                planTimeThreeStr = jsonObject.getString("FACTIVITY3QTY");

                if (StringUtils.isNotBlank(planTimeStr)) {
                    planTime = new BigDecimal(planTimeStr);
                }
                if (StringUtils.isNotBlank(finishCountStr)) {
                    finishCount = new BigDecimal(finishCountStr);
                }
                if (StringUtils.isNotBlank(planTimeThreeStr)) {
                    planTimeThree = new BigDecimal(planTimeThreeStr);
                }

                workHourReportDO.setPlanTime(planTime.setScale(2, BigDecimal.ROUND_HALF_UP));
                workHourReportDO.setFinishCount(finishCount.setScale(2, BigDecimal.ROUND_HALF_UP));
                workHourReportDO.setPlanTimeThree(planTimeThree.setScale(2, BigDecimal.ROUND_HALF_UP));
                workHourReportDO.setCountWorkTime((planTime.multiply(finishCount)).add(planTimeThree).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
                allList.add(workHourReportDO);
            }

            LOGGER.info("allList.size()=" + allList.size());
            return allList;


        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    // 获取工序汇报汇总表
    private List<WorkHourReportReptDO> getSFCOperationReportRpt() {
        K3CloudApi api = new K3CloudApi();
        List<String> centerIdList = new ArrayList<>(10);
        centerIdList.add("CC01-2");
        centerIdList.add("CC02-1");
        centerIdList.add("CC03-1");
        centerIdList.add("CC04-1");
        centerIdList.add("JC01-1");
        centerIdList.add("JC01-2");
        centerIdList.add("XC01-1");
        centerIdList.add("XC04-1");
        centerIdList.add("XC05-1");
        centerIdList.add("XC06-1");
        StringBuilder centerIds = new StringBuilder();
        for (String centerId : centerIdList) {
            centerIds.append("{\"FNumber\":\"" + centerId + "\"},");
        }

        centerIds = centerIds.deleteCharAt(centerIds.length() - 1);
        String limit = "50";
        Integer startRow = 0;
        //client.InitClient("63ad55771faa8f", "appID", "appSec", "userName", 2052, "100", "http://117.78.51.85/K3Cloud/");
        String json = "{\"FieldKeys\":\"FDATE,FEMPLOYEEID,FPLANSETTIME,FREALPROCESSTIME,FWORKCENTERID\",\"SchemeId\":\"\",\"StartRow\":" + startRow + ",\"Limit\":" + limit + ",\"IsVerifyBaseDataField\":\"true\",\"FilterString\":[],\"Model\":{\"FProcessOrgId\":{\"FNumber\":\"100\"},\"FProWorkShopIDS\":\"\",\"FBeginDate\":\"2024-05-23\",\"FEndDate\":\"2024-05-23\",\"FBeginMaterialId\":{\"FNumber\":\"\"},\"FEndMaterialId\":{\"FNumber\":\"\"},\"FWorkCenterIds\":[" + centerIds + "],\"FShiftGroupIds\":[{\"FNumber\":\"\"}],\"FEquipmentIds\":[{\"FNumber\":\"\"}],\"FEmployeeIds\":[{\"FStaffNumber\":\"\"}],\"FTimeUnit\":\"B\"}}";
        String sFormId = "SFC_OperationReportRpt";
        try {
            String apiResult = api.getSysReportData(sFormId, json);
            if (StringUtils.isBlank(apiResult)) {
                return null;
            }

            // System.out.println("apiResult=" + apiResult);

            JSONObject jsonObject = JSONObject.parseObject(apiResult);

            JSONObject result = jsonObject.getJSONObject("Result");
            LOGGER.info("result=" + result);

            Boolean isSuccess = result.getBoolean("IsSuccess");
            String rowCountStr = result.getString("RowCount");
            if (isSuccess == null || StringUtils.isBlank(rowCountStr) || Integer.valueOf(rowCountStr) == 0 || !isSuccess) {
                return null;
            }


            Integer rowCount = Integer.valueOf(rowCountStr);
            LOGGER.info("rowCount=" + rowCount);

            List<JSONArray> rows = result.getList("Rows", JSONArray.class);
            if (CollectionUtils.isEmpty(rows)) {
                return null;
            }

            List<WorkHourReportReptDO> resultList = rows.stream().map(entity -> {
                WorkHourReportReptDO workHourReportReptDO = new WorkHourReportReptDO();
                workHourReportReptDO.setDate(entity.getString(0));
                workHourReportReptDO.setEmployeeId(entity.getString(1));
                BigDecimal planSetTime = entity.getBigDecimal(2);
                if (planSetTime == null) {
                    planSetTime = BigDecimal.ZERO;
                }
                workHourReportReptDO.setPlanSetTime(planSetTime);
                workHourReportReptDO.setRealProcessTime(entity.getBigDecimal(3));
                workHourReportReptDO.setWorkCenterId(entity.getString(4));
                return workHourReportReptDO;
            }).filter(entity -> StringUtils.isNotBlank(entity.getEmployeeId())).collect(Collectors.toList());

            LOGGER.info("resultList=" + resultList.size());

            if (rowCount == 1) {
                return resultList;
            }

            int pageCount = getPageCount(rowCount, Integer.valueOf(limit));
            LOGGER.info("pageCount=" + pageCount);


        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    private int getPageCount(int totalCount, int pageSize) {
        return totalCount % pageSize == 0 ? totalCount / pageSize : (totalCount / pageSize + 1);
    }

    // 智慧车间MES->智慧车间->车间报工执行->辅助工时列表
    private List<WorkHourReportDO> getSFCUnproductiveTime(Integer startRow, Integer topRowCount, String startDate, String endDate) throws Exception {
        List<WorkHourReportDO> allList = new ArrayList<>();

        String json = "{\"FormId\":\"SFC_UnproductiveTime\",\"FieldKeys\":\"FDATE,FWORKER,F_PPIV_CZGXM,FWORKTIME,FWORKTYPE,FDOCUMENTSTATUS\"," + "\"FilterString\":[{\"Left\":\"(\",\"FieldName\":\"FDATE\",\"Compare\":\">=\",\"Value\":\"" + startDate + "\",\"Right\":\")\",\"Logic\":\"0\"}," + "{\"Left\":\"(\",\"FieldName\":\"FDATE\",\"Compare\":\"<\",\"Value\":\"" + endDate + "\",\"Right\":\")\",\"Logic\":\"0\"}," + "{\"Left\":\"(\",\"FieldName\":\"FDOCUMENTSTATUS\",\"Compare\":\"=\",\"Value\":\"C\",\"Right\":\")\",\"Logic\":\"0\"}," +
//                "{\"Left\":\"(\",\"FieldName\":\"FPRDSHOP\",\"Compare\":\"IN\",\"Value\":\"489018,439253,439252,318400,318397,318398,318404,318399\",\"Right\":\")\",\"Logic\":\"0\"}"+
                "]," + "\"OrderString\":\"\",\"TopRowCount\":" + topRowCount + ",\"StartRow\":" + startRow + ",\"Limit\":10000,\"SubSystemId\":\"\"}";

        K3CloudApi api = new K3CloudApi();
        String apiResult = api.billQuery(json);

        if (StringUtils.isBlank(apiResult)) {
            return null;
        }

        // System.out.println("apiResult=" + apiResult);

        if (StringUtils.contains(apiResult, "ResponseStatus")) {
            LOGGER.error(apiResult.toString());
            throw new ReportExcepiton(BizErrorCode.SYSTEM_BUSY_ERROR);
        }


        JSONArray jsonArray = JSONArray.parse(apiResult);

        LOGGER.info("jsonArray.size()=" + jsonArray.size());

        if (jsonArray.size() == 0) {
            return null;
        }

        JSONObject jsonObject = null;
        String employeeName = null;
        BigDecimal planTime = BigDecimal.ZERO;

        String planTimeStr;

        for (Object object : jsonArray) {
            jsonObject = JSONObject.parseObject(object.toString());

            employeeName = jsonObject.getString("F.PPIV.CZGXM");

            if (StringUtils.isBlank(employeeName)) {
                continue;
            }

            WorkHourReportDO workHourReportDO = new WorkHourReportDO();
            workHourReportDO.setDate(jsonObject.getString("FDATE"));
            workHourReportDO.setEmployeeId(jsonObject.getString("FWORKER"));
            workHourReportDO.setEmployeeName(employeeName);

            planTimeStr = jsonObject.getString("FWORKTIME");

            if (StringUtils.isNotBlank(planTimeStr)) {
                planTime = new BigDecimal(planTimeStr);
            }
            workHourReportDO.setCountWorkTime(planTime.setScale(2, BigDecimal.ROUND_HALF_UP));
            allList.add(workHourReportDO);
        }
        LOGGER.info("allList.size()=" + allList.size());
        return allList;
    }
}
